/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License Version
 *  3 as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
 *  USA.
 */

#include <iostream>
#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QtCore/QStringList>
#include <QtGui/QApplication>

#include <logger/logger.h>
#include <log4Qt/propertyconfigurator.h>

#include <stdlib.h>

#include <helpers/connector.h>

using namespace Opl::Helpers;

static bool wantsToQuit;
static QString host = "localhost";
static qint16 port = 51999;


static Opl::Helpers::Connector optra;

static bool sendcommand(const QString& command)
{
	if (command.trimmed().compare(QLatin1String("quit")) == 0) {
		exit(EXIT_SUCCESS);

	} else {
		optra.Send(command);
		return true;
	}

	return false;
}


static void interactive()
{
	QTextStream qin(stdin, QFile::ReadOnly);
	const char* qscript_prompt = "optra>";
	const char* prompt = qscript_prompt;
	QString code;
	forever {
		QString line;

		printf("%s", prompt);
		fflush(stdout);

		line = qin.readLine();

		if (line.isNull()) {
			break;
		}

		code += line;
		code += QLatin1Char('\n');

		if (line.trimmed().isEmpty()) {
			continue;

		} else if (!sendcommand(code)) {
			exit(EXIT_FAILURE);

		} else {
			//optra.Send(code);
			//sendcommand(code);
			// QScriptValue result = sendcommand(code);//, QLatin1String("typein"));

			code.clear();
			prompt = qscript_prompt;

			if (wantsToQuit) {
				break;
			}
		}
	}
}

void myMessageOutput(QtMsgType type, const char* msg)
{
	//in this function, you can write the message to any stream!
	switch (type) {
		case QtDebugMsg:
			Log4Qt::Logger::logger("Optra")->debug(msg);
			break;

		case QtWarningMsg:
			Log4Qt::Logger::logger("Optra")->warn(msg);
			break;

		case QtCriticalMsg:
			Log4Qt::Logger::logger("Optra")->error( msg);
			break;

		case QtFatalMsg:
			Log4Qt::Logger::logger("Optra")->fatal(msg);
			abort();
	}
}

int main(int argc, char** argv)
{
	qInstallMsgHandler(myMessageOutput);
	QApplication* app;

	if (argc >= 2 && !qstrcmp(argv[1], "-tty")) {
		++argv;
		--argc;
		app = new QApplication(argc, argv, QApplication::Tty);

	} else {
		app = new QApplication(argc, argv);
	}

	Log4Qt::PropertyConfigurator::configure(app->applicationDirPath() + "/console.properties");
	Log4Qt::Logger::logger("Optra")->info("------------------------Start : %1------------------------", QDate::currentDate().toString());
	ConnectorSetup setup;
	setup.host = "localhost";
	setup.port = 51999;
	setup.reconnectTime = 20;
	optra.Setup(setup);
	optra.Start();

	if (! *++argv) {
		interactive();
		return EXIT_SUCCESS;
	}

	while (const char* arg = *argv++) {
		QString fn = QString::fromLocal8Bit(arg);

		if (fn == QLatin1String("-i")) {
			interactive();
			break;
		}

		QString contents;
		int lineNumber = 1;

		if (fn == QLatin1String("-")) {
			QTextStream stream(stdin, QFile::ReadOnly);
			contents = stream.readAll();

		} else {
			QFile file(fn);

			if (file.open(QFile::ReadOnly)) {
				QTextStream stream(&file);
				contents = stream.readAll();
				file.close();

				// strip off #!/usr/bin/env qscript line
				if (contents.startsWith("#!")) {
					contents.remove(0, contents.indexOf("\n"));
					++lineNumber;
				}

				if (!sendcommand(contents)) {
					return EXIT_FAILURE;
				}
			}
		}

		if (contents.isEmpty()) {
			continue;
		}
	}

	delete app;
	//Log4Qt::Logger::logger("Optra")->info("Return code : %1", ret);
	Log4Qt::Logger::logger("Optra")->info("-------------------------End : %1------------------------", QDate::currentDate().toString());
	return EXIT_SUCCESS;
}
